package com.imdroid.lite.activities;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Message;
import android.text.InputType;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;

import com.baidu.mapapi.BMapManager;
import com.baidu.mapapi.LocationListener;
import com.baidu.mapapi.MKLocationManager;
import com.imdroid.lite.IMDroid;
import com.imdroid.lite.R;
import com.imdroid.lite.model.Team;
import com.imdroid.lite.process.ProcessFactory;
import com.imdroid.lite.process.TeamProcess;

public class TeamSelectActivity extends BaseActivity implements
		SensorEventListener, LocationListener {
	/**
	 * The tag of the class
	 */
	private static final String TAG = "TeamSelectActivity";
	/**
	 * The sensor manager
	 */
	private SensorManager sensorManager;
	/**
	 * The sensor of accelerometer
	 */
	private Sensor accelerometer;
	/**
	 * The map manager
	 */
	private BMapManager bMapManager;
	/**
	 * The location manager
	 */
	private MKLocationManager locationManager;
	/**
	 * The data in the list
	 */
	private List<Map<String, Object>> listData;
	/**
	 * The adapter of the team search view
	 */
	private SimpleAdapter ListDataAdapter;
	/**
	 * The list view of the team selection
	 */
	private ListView teamListView;
	/**
	 * The text view of text view
	 */
	private EditText keyWordEditText;

	/**
	 * The event of search the team
	 */
	private static final int EVENT_JOIN = 102;
	private static final int EVENT_GET_ACCESS_CODE = 104;
	private static final int EVENT_CHECK = 105;
	private static final int EVENT_ERROR = 99;

	/**
	 * The maxmium tolerance
	 */
	private static final float tolerance = (float) 8;
	/**
	 * The last value of accelerometer
	 */
	private static boolean allowNearby = true;
	/**
	 * The current location
	 */
	private Location currentLcation = null;
	/**
	 * if need to close the location manager when exit this activity
	 */
	private boolean keepLocationLive = false;
	/**
	 * The access code of the target team
	 */
	private String targetTeamAccessCode = null;

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 */
	public void onCreate(Bundle savedInstanceState) {
		// 初始化Activity
		super.onCreate(savedInstanceState);
		setContentView(R.layout.team_select);
		// 关键字搜查框
		keyWordEditText = (EditText) this.findViewById(R.id.team_keyword);
		keyWordEditText
				.setOnEditorActionListener(new EditText.OnEditorActionListener() {
					public boolean onEditorAction(TextView v, int actionId,
							KeyEvent event) {
						if (actionId == EditorInfo.IME_ACTION_DONE) {
							Log.d(TAG, "Done press");
							InputMethodManager imm = (InputMethodManager) v
									.getContext().getSystemService(
											Context.INPUT_METHOD_SERVICE);
							imm.hideSoftInputFromWindow(v.getWindowToken(), 0);

							new InSearchsBarTask().execute(keyWordEditText
									.getText() + "");
							return true;
						}
						return false;
					}

				});
		// 队伍选择框
		teamListView = (ListView) this.findViewById(R.id.team_selection_list);
		teamListView.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				select(arg2);
			}

		});
		// 注册location listener得到当前位置
		IMDroid app = (IMDroid) this.getApplication();
		bMapManager = app.mBMapMan;
		locationManager = bMapManager.getLocationManager();

		// 注册感應器
		allowNearby = true;
		sensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);
		accelerometer = sensorManager
				.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onResume()
	 */
	@SuppressWarnings("deprecation")
	protected void onResume() {
		Log.d(TAG, "onResume...");
		super.onResume();
		if (bMapManager != null) {
			bMapManager.start();
		}
		// 注册感應器
		sensorManager.registerListener(this, accelerometer,
				SensorManager.SENSOR_ACCELEROMETER);
		// 注册GPS
		locationManager.enableProvider(MKLocationManager.MK_GPS_PROVIDER);
		locationManager.enableProvider(MKLocationManager.MK_NETWORK_PROVIDER);
		locationManager.requestLocationUpdates(this);

		try {
			// 获取数据
			listData = getList(getTeams(""));
			// 设置adapter
			ListDataAdapter = new SimpleAdapter(this, listData,
					R.layout.team_select_item, new String[] { "display", "lock" },
					new int[] { R.id.team_select_item, R.id.lock });

			teamListView.setAdapter(ListDataAdapter);
		} catch (Exception e) {
			// 处理错误
			messageHandler.obtainMessage(EVENT_ERROR, e.getMessage())
					.sendToTarget();
			e.printStackTrace();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onDestroy()
	 */
	protected void onPause() {
		Log.d(TAG, "onPause...");
		// 注销感應器
		sensorManager.unregisterListener(this, accelerometer);
		locationManager.removeUpdates(this);
		if (!keepLocationLive) {
			// Enable location manager
			locationManager.disableProvider(MKLocationManager.MK_GPS_PROVIDER);
			locationManager
					.disableProvider(MKLocationManager.MK_NETWORK_PROVIDER);

			if (bMapManager != null) {
				bMapManager.stop();
			}
		}
		super.onPause();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * android.hardware.SensorEventListener#onSensorChanged(android.hardware
	 * .SensorEvent)
	 */
	public void onSensorChanged(SensorEvent event) {
		int sensorType = event.sensor.getType();
		float[] values = event.values;
		
		if (sensorType == Sensor.TYPE_ACCELEROMETER) {
			float motion = (values[0] > values[1] ? values[0] : values[1]);
			motion = (motion > values[2] ? motion : values[2]);
			// Log.d(TAG, "start search nearby---" + motion);
			float shock = Math.abs((float) (motion - 9.8));
			//Log.d(TAG, "start search nearby---" + allowNearby + "--"+shock);
			if (allowNearby && (shock > tolerance)) {
				Log.d(TAG, "start search nearby---" + shock);
				// 查询期间，设置成不响应
				allowNearby = false;
				new InSearchsBarTask().execute("NEARBY");
			}
		}

	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * android.hardware.SensorEventListener#onAccuracyChanged(android.hardware
	 * .Sensor, int)
	 */
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
		return;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.baidu.mapapi.LocationListener#onLocationChanged(android.location.
	 * Location)
	 */
	public void onLocationChanged(Location location) {
		currentLcation = location;
		// Log.d(TAG,
		// currentLcation.getLatitude() + "||"
		// + currentLcation.getLongitude());

	}

	/**
	 * Search from the server
	 * 
	 * @param view
	 *            the button of search
	 */
	public void search(View view) {
		new InSearchsBarTask().execute(keyWordEditText.getText() + "");
	}

	/**
	 * Return to home activity
	 * 
	 * @param view
	 *            the button of return;
	 */
	public void back(View view) {
		this.finish();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.imdroid.lite.activities.BaseActivity#actionInProgressBar(java.lang
	 * .Object[])
	 */
	protected void actionInProgressBar(Object... params) throws Exception {
		int action = (Integer) params[0];
		Object object = params[1];

		switch (action) {
		case EVENT_JOIN:
			// 取得Team对象
			Team team = (Team) object;
			joinTeam(team);
			break;
		case EVENT_GET_ACCESS_CODE:
			Team t = (Team) object;
			retrieveAccessCode(t);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * com.imdroid.lite.activities.BaseActivity#processedMessage(android.os.
	 * Message)
	 */
	protected void processedMessage(Message msg) throws Exception {
		super.processedMessage(msg);
		switch (msg.what) {
		case EVENT_CHECK:
			checkAccessCode((Team) msg.obj);
			break;
		}
	}

	/**
	 * Got to map activity
	 * 
	 * @param view
	 *            the button of return;
	 */
	private void select(int index) {
		Map<String, Object> map = listData.get(index);
		final Team team = (Team) map.get("object");
		try {
			// 如果进入自己的队伍，无须校验密码
			if (IMDroid.getUser().getUser_id() == team.getTeamId()) {
				new TeamSelectActivity.InProgressBarTask(
						TeamSelectActivity.this, R.string.team_wait_title,
						R.string.team_wait_join).execute(EVENT_JOIN, team);
				return;
			}
			// 如果进入别人的队伍，首先从服务起上提取密码
			new TeamSelectActivity.InProgressBarTask(TeamSelectActivity.this,
					R.string.team_wait_title, R.string.team_wait_join).execute(
					EVENT_GET_ACCESS_CODE, team);

		} catch (Exception e) {
			Toast.makeText(TeamSelectActivity.this, "Error:" + e.getMessage(),
					Toast.LENGTH_SHORT).show();
			e.printStackTrace();
		}

	}

	/**
	 * Join into the team
	 * 
	 * @param teamId
	 *            the team id
	 * @throws Exception
	 */
	private void joinTeam(Team team) throws Exception {
		Log.d(TAG, "choose:" + team.getTeamId());
		// 收起键盘
		View v = this.findViewById(R.id.team_keyword);
		InputMethodManager imm = (InputMethodManager) this
				.getSystemService(Context.INPUT_METHOD_SERVICE);
		imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
		// 先停止location的获取
		keepLocationLive = true;

		// 增加到历史队伍里面
		if (team.getTeamId() != IMDroid.getUser().getUser_id())
			Team.addHistricalTeams(team);
		// 加入队伍
		TeamProcess process = (TeamProcess) ProcessFactory
				.getProcess(TeamProcess.class);
		process.joinTeam(team);

		// 跳转到地图页面
		Activity context = TeamSelectActivity.this;
		context.startActivity(new Intent(context, TeamMapActivity.class));
		context.finish();

	}

	/**
	 * Get the data of list view
	 * 
	 * @param keyWord
	 *            the keyWord to search
	 * @return the data of list vi
	 * @throws Exception
	 */
	private List<Map<String, Object>> getList(Collection<Team> teams)
			throws Exception {
		List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
		// Collection<Team> teams = getTeams(keyWord);
		for (Team team : teams) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("display", team.getTeamName());
			map.put("object", team);
			String acc = team.getTeamAccessCode();
			map.put("lock", acc == null || acc.trim().equals("") ? R.drawable.lock_off : R.drawable.lock_on);
			list.add(map);
		}
		return list;
	}

	/**
	 * Search the team
	 * 
	 * @param keyWord
	 *            the keyWord to search
	 * @return the team according the keyword
	 * @throws Exception
	 */
	private Collection<Team> getTeams(String keyWord) throws Exception {
		Log.d(TAG, "Load default team");
		Collection<Team> teams = new ArrayList<Team>();

		if (keyWord == null || keyWord.length() <= 0) {
			Log.d(TAG, "Load default team");
			Team defaultTeam = IMDroid.getUser().getDefualtTeam();
			teams.add(defaultTeam);

			Collection<Team> his = Team.getHistoricalTeams();
			teams.addAll(his);
		} else {
			TeamProcess process = (TeamProcess) ProcessFactory
					.getProcess(TeamProcess.class);
			teams.addAll(process.searchTeam(keyWord));
		}
		return teams;
	}

	/**
	 * Search the team
	 * 
	 * @param keyWord
	 *            the keyWord to search
	 * @return the team according the keyword
	 * @throws Exception
	 */
	private Collection<Team> getNearBy() throws Exception {
		Log.d(TAG, "Load default team near by");
		Collection<Team> teams = new ArrayList<Team>();
		TeamProcess process = (TeamProcess) ProcessFactory
				.getProcess(TeamProcess.class);
		teams.addAll(process.searchTeamNearby(currentLcation));
		allowNearby = true;
		return teams;
	}

	/**
	 * Retrive the accoss of the target team
	 * 
	 * @param team
	 *            the target team want to join
	 * @throws Exception
	 */
	private void retrieveAccessCode(Team team) throws Exception {
		Log.d(TAG, "Get the team access code");
		TeamProcess process = (TeamProcess) ProcessFactory
				.getProcess(TeamProcess.class);
		targetTeamAccessCode = process.getTeamAccessCode(team.getTeamId());
		this.sendMessage(EVENT_CHECK, team);
		Log.d(TAG, "targetTeamAccessCode ：" + targetTeamAccessCode);
	}

	/**
	 * Validate the access code;
	 * 
	 * @param accessCode
	 *            the access code
	 * @throws Exception
	 */
	private void checkAccessCode(final Team team) throws Exception {
		Log.d(TAG, "2.1-------" + targetTeamAccessCode);
		// 如果对方没有设置密码
		if (targetTeamAccessCode == null
				|| targetTeamAccessCode.trim().length() <= 0
				|| targetTeamAccessCode.trim().equals("NONE")) {

			new TeamSelectActivity.InProgressBarTask(TeamSelectActivity.this,
					R.string.team_wait_title, R.string.team_wait_join).execute(
					EVENT_JOIN, team);
			// runInProgressBar(R.string.team_wait_title,
			// R.string.team_wait_join,
			// EVENT_JOIN, team);
			return;
		}
		Log.d(TAG, "3-------");
		// 如果对方有设置密码，则弹出输入框检验
		final EditText input = new EditText(this);
		input.setInputType(InputType.TYPE_NUMBER_FLAG_SIGNED);
		input.setOnEditorActionListener(new OnEditorActionListener() {
			@Override
			public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
				accessCodeConfirm(input, team);
				return true;
			}
		});
		
		final AlertDialog.Builder builder = new AlertDialog.Builder(this);
		// builder.setTitle(R.string.team_join);
		builder.setMessage(R.string.team_join_check);
		builder.setView(input);
		builder.setPositiveButton(R.string.team_confirm, new OnClickListener() {
			public void onClick(DialogInterface arg0, int arg1) {
				accessCodeConfirm(input, team);
			}
		});
		builder.setNegativeButton(R.string.team_cancel, null);
		builder.show();
	}
	
	private void accessCodeConfirm(EditText input, Team team){
		String inputAccessCode = input.getText().toString();
		// 如果没有输入密码
		if (inputAccessCode == null
				|| inputAccessCode.trim().length() <= 0) {
			TeamSelectActivity.this.showAlert(R.string.team_join,
					R.string.team_join_check_empty);
			return;
		}
		// 如果密码不正确
		if (!inputAccessCode.equals(targetTeamAccessCode)) {
			TeamSelectActivity.this.showAlert(R.string.team_join,
					R.string.team_join_check_fail);
			return;
		}
		// 进入组队模式
		new TeamSelectActivity.InProgressBarTask(
				TeamSelectActivity.this, R.string.team_wait_title,
				R.string.team_wait_join).execute(EVENT_JOIN, team);
		// runInProgressBar(R.string.team_wait_title,
		// R.string.team_wait_join, EVENT_JOIN, team);
		return;
	}

	/**
	 * The ansyc task in progress bar
	 * 
	 */
	protected class InSearchsBarTask extends AsyncTask<Object, Void, Exception> {
		ProgressDialog progressDialog;

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#onPreExecute()
		 */
		protected void onPreExecute() {
			super.onPreExecute();
			Context context = TeamSelectActivity.this;
			progressDialog = ProgressDialog.show(context,
					context.getString(R.string.team_wait_title),
					context.getString(R.string.team_wait_searching));
			progressDialog.show();
			progressDialog.setCancelable(true);

		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#doInBackground(Params[])
		 */
		protected Exception doInBackground(Object... params) {
			try {
				String keyword = (String) params[0];
				List<Map<String, Object>> result;
				if ("NEARBY".equals(keyword))
					result = getList(getNearBy());
				else
					result = getList(getTeams(keyword));
				// 更新adapter
				listData.clear();
				listData.addAll(result);

			} catch (Exception ex) {
				ex.printStackTrace();
				return ex;
			}
			return null;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
		 */
		protected void onPostExecute(Exception result) {
			super.onPostExecute(result);
			progressDialog.dismiss();

			if (result != null) {
				String errorMessage = result.getMessage();
				Toast.makeText(TeamSelectActivity.this, errorMessage,
						Toast.LENGTH_SHORT).show();
			} else {
				ListDataAdapter.notifyDataSetChanged();
			}
		}
	}
}
